<script lang="ts" setup>
// Vue API 和 Element Plus 组件已通过 Vite 自动导入
import type { FormInstance, FormRules } from "element-plus"

// 显式定义组件名称
defineOptions({
  name: "CommonCreateDialog"
})

const props = defineProps<Props>()

const emit = defineEmits<Emits>()

// 表单字段配置类型
interface FormField {
  prop: string
  label: string
  placeholder: string
  required?: boolean
  minLength?: number
  maxLength?: number
  pattern?: RegExp
  patternMessage?: string
  type?: "input" | "select" // 字段类型
  options?: Array<{ label: string, value: string }> // 选择框选项
}

// 弹窗配置类型
interface DialogConfig {
  title: string
  description: string
  fields: FormField[]
  successMessage: string
  confirmButtonText?: string // 确认按钮文字，默认为"创建"
}

interface Props {
  modelValue: boolean
  config: DialogConfig
  extraData?: Record<string, any> // 额外数据，如channelId等
  initialData?: Record<string, any> // 初始数据，用于编辑模式
}

interface Emits {
  (e: "update:modelValue", value: boolean): void
  (e: "confirm", data: any): void
}

const formRef = ref<FormInstance>()
const loading = ref(false)
const visible = ref(false)

// 动态生成表单数据
const formData = reactive<Record<string, string>>({})

// 动态生成表单验证规则
const formRules = computed<FormRules>(() => {
  const rules: FormRules = {}

  props.config.fields.forEach((field: FormField) => {
    const fieldRules: any[] = []

    if (field.required !== false) {
      fieldRules.push({
        required: true,
        message: `请输入${field.label}`,
        trigger: "blur"
      })
    }

    if (field.minLength || field.maxLength) {
      fieldRules.push({
        min: field.minLength || 1,
        max: field.maxLength || 100,
        message: `长度在 ${field.minLength || 1} 到 ${field.maxLength || 100} 个字符`,
        trigger: "blur"
      })
    }

    if (field.pattern) {
      fieldRules.push({
        pattern: field.pattern,
        message: field.patternMessage || "格式不正确",
        trigger: "blur"
      })
    }

    rules[field.prop] = fieldRules
  })

  return rules
})

// 监听外部 modelValue 变化
watch(
  () => props.modelValue,
  (newVal: boolean) => {
    visible.value = newVal
    if (newVal) {
      resetForm()
    }
  },
  { immediate: true }
)

// 监听内部 visible 变化
watch(visible, (newVal: boolean) => {
  emit("update:modelValue", newVal)
})

// 重置表单数据结构
function resetFormData(config: DialogConfig) {
  // 清空现有数据
  Object.keys(formData).forEach((key) => {
    delete formData[key]
  })

  // 根据配置初始化表单字段
  config.fields.forEach((field) => {
    // 如果有初始数据，使用初始数据，否则使用空值
    formData[field.prop] = props.initialData?.[field.prop] || ""
  })
}

// 监听配置变化，重置表单数据
watch(
  () => props.config,
  (newConfig: DialogConfig) => {
    resetFormData(newConfig)
  },
  { immediate: true, deep: true }
)

// 监听初始数据变化
watch(
  () => props.initialData,
  () => {
    resetFormData(props.config)
  },
  { deep: true }
)

// 重置表单
function resetForm() {
  resetFormData(props.config)
  formRef.value?.clearValidate()
}

// 取消操作
function handleCancel() {
  visible.value = false
}

// 确认创建
async function handleConfirm() {
  if (!formRef.value) return

  try {
    await formRef.value.validate()
    loading.value = true

    // 模拟API调用
    await new Promise(resolve => setTimeout(resolve, 1000))

    // 生成数据，包含表单数据和额外数据
    const resultData = {
      ...formData,
      ...props.extraData
    }

    emit("confirm", resultData)
    visible.value = false
  } catch (error) {
    console.error("表单验证失败:", error)
  } finally {
    loading.value = false
  }
}
</script>

<template>
  <el-dialog
    v-model="visible"
    :title="config.title"
    width="520px"
    :close-on-click-modal="true"
    :close-on-press-escape="true"
    class="common-create-dialog"
  >
    <div class="dialog-content">
      <p class="dialog-description">
        {{ config.description }}
      </p>

      <el-form
        ref="formRef"
        :model="formData"
        :rules="formRules"
        label-position="top"
        class="create-form"
      >
        <el-form-item
          v-for="field in config.fields"
          :key="field.prop"
          :label="field.label"
          :prop="field.prop"
        >
          <el-input
            v-if="!field.type || field.type === 'input'"
            v-model="formData[field.prop]"
            :placeholder="field.placeholder"
            clearable
          />
          <el-select
            v-else-if="field.type === 'select'"
            v-model="formData[field.prop]"
            :placeholder="field.placeholder"
            clearable
            style="width: 100%"
          >
            <el-option
              v-for="option in field.options"
              :key="option.value"
              :label="option.label"
              :value="option.value"
            />
          </el-select>
        </el-form-item>
      </el-form>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleCancel">取消</el-button>
        <el-button
          type="primary"
          @click="handleConfirm"
          :loading="loading"
          class="confirm-button"
        >
          {{ config.confirmButtonText || "创建" }}
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
.common-create-dialog {
  :deep(.el-dialog) {
    border-radius: 12px;
    overflow: hidden;
  }

  :deep(.el-dialog__header) {
    padding: 32px 32px 0;
    border-bottom: none;

    .el-dialog__title {
      font-size: 20px;
      font-weight: 700;
      color: var(--el-text-color-primary);
      line-height: 1.2;
    }

    .el-dialog__headerbtn {
      top: 24px;
      right: 24px;
      width: 32px;
      height: 32px;

      .el-dialog__close {
        font-size: 18px;
        color: var(--el-text-color-regular);

        &:hover {
          color: var(--el-text-color-primary);
        }
      }
    }
  }

  :deep(.el-dialog__body) {
    padding: 20px 32px 0;
  }

  :deep(.el-dialog__footer) {
    padding: 24px 32px 32px;
    border-top: none;
  }
}

.dialog-content {
  .dialog-description {
    margin: 0 0 32px 0;
    font-size: 14px;
    color: var(--el-text-color-regular);
    line-height: 1.5;
    font-weight: 400;
  }
}

.create-form {
  :deep(.el-form-item) {
    margin-bottom: 24px;

    .el-form-item__label {
      font-size: 14px;
      font-weight: 500;
      color: var(--el-text-color-primary);
      margin-bottom: 12px;
      padding: 0;
      line-height: 1.2;
    }

    .el-input {
      height: 40px;

      .el-input__wrapper {
        padding: 10px 16px;
        border-radius: 8px;
        border: 1px solid var(--el-border-color);
        height: 40px;

        &:hover {
          border-color: var(--el-border-color-darker);
        }

        &.is-focus {
          border-color: var(--el-color-primary);
          box-shadow: 0 0 0 3px var(--el-color-primary-light-8);
        }
      }

      .el-input__inner {
        font-size: 14px;
        color: var(--el-text-color-primary);
        height: 18px;

        &::placeholder {
          color: var(--el-text-color-placeholder);
          font-weight: 400;
        }
      }
    }
  }

  // 最后一个表单项的间距
  :deep(.el-form-item:last-child) {
    margin-bottom: 32px;
  }
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 16px;

  .el-button {
    padding: 8px 20px;
    font-size: 14px;
    font-weight: 500;
    border-radius: 6px;
    height: 36px;
    min-width: 70px;

    &:not(.el-button--primary) {
      background-color: var(--el-bg-color);
      border-color: var(--el-border-color);
      color: var(--el-text-color-regular);

      &:hover {
        background-color: var(--el-fill-color-light);
        border-color: var(--el-border-color-darker);
        color: var(--el-text-color-primary);
      }
    }
  }

  .confirm-button {
    background-color: var(--el-color-primary, #030212) !important;
    border-color: var(--el-color-primary, #030212) !important;
    color: #ffffff !important;
    font-weight: 500;

    &:hover,
    &:focus {
      background-color: var(--el-color-primary-light-3, #333333) !important;
      border-color: var(--el-color-primary-light-3, #333333) !important;
    }

    &:active {
      background-color: var(--el-color-primary-dark-2, #1a1a1a) !important;
      border-color: var(--el-color-primary-dark-2, #1a1a1a) !important;
    }
  }
}
</style>
